from django.db import models

# Create your models here.
"""
django 操作数据库:
    类               对应数据库的   表
    类变量(类属性)    对应数据库的   字段
    类对象(方法/函数) 对应数据库的   数据行(就是插入表数据的意思)
"""


class Publisher(models.Model):
    """出版社表"""
    # 从Book表中分离出来, 实现一对多的外键
    # unique=True 设置该字段是唯一
    pub = models.CharField(max_length=50, null=True,
                           verbose_name='出版社', unique=True)
    dates = models.DateTimeField(auto_now=True, verbose_name='添加时间')

    def __str__(self) -> str:
        return f"出版社: {self.pub}, 添加时间: {self.dates}"

    class Meta:
        """操作数据库中的表"""
        db_table = 'mypublisher'  # 重命名表名
        verbose_name = '出版社表(Publisher)'
        verbose_name_plural = '出版社表(Publisher)'


class Author(models.Model):
    """作者表"""
    name = models.CharField(max_length=10, verbose_name='名字')
    age = models.IntegerField(null=True, default=1, verbose_name='年龄')
    email = models.EmailField(verbose_name='邮箱', default='111@live.com')
    dates = models.DateTimeField(auto_now=True, verbose_name='添加时间')

    # 如果不重写 def __str__()方法,则admin后台管理页面不会直接显示名字,年龄,邮箱这些,而是默认显示Author object
    def __str__(self) -> str:
        return f"名字: {self.name}, 年龄: {self.age}, 邮箱: {self.email}"

    class Meta:
        """操作数据库中的表"""
        db_table = 'myauthor'  # 重命名表名
        verbose_name = '作者表(Author)'
        verbose_name_plural = '作者表(Author)'


# Create your models here.
class Book(models.Model):
    """ 创建名为Book(书籍)的数据表, 中途添加字段必须提供默认值
        DateTimeField和DateField和TimeField存储的内容分别对应着datetime(),date(),time()三个对象。
    """

    # 创建字段, 如果需要添加索引, 只需要在传参里面追加, db_index=True 即可. verbose_name是admin后台管理界面的名字
    # 对应数据库的varchar(30). 表明该字段的类型
    name = models.CharField(max_length=30, unique=True,
                            null=True, verbose_name='书名')
    # 对应该字段的类型为decimal(7, 2)
    price = models.DecimalField(
        decimal_places=2, max_digits=6, verbose_name='定价', default=9999)
    market_price = models.DecimalField(
        decimal_places=2, max_digits=6, verbose_name='市场价', default=9999)

    # 关联外链, 关联出版社, 对于出版社表是一对多, 对于Book书籍表是多对一
    # null=True不能为空 如果不加的话,可能会出现不能添加书籍的错误
    publisher = models.ForeignKey(
        Publisher, models.PROTECT, null=True, verbose_name='出版社(外链)')

    # 关联外链,多对多, 多个作者修改同一本书
    # authors = models.ManyToManyField(Author, null=True, verbose_name='多,作者(外链)')

    """
    参数:
        - DateField.auto_now: 每次保存对象时，自动设置该字段为当前时间(取值:True/False)。
        - DateField.auto_now_add: 当对象第一次被创建时自动设置当前时间(取值:True/False)。
        - DateField.default: 设置当前时间(取值:字符串格式时间如: '2019-6-1')。
        - 以上三个参数只能多选一
    """
    dates = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')

    def __str__(self) -> str:
        """这里返回作用于数据库select * form *** 的语句"""
        # 多,作者(外链): {self.authors}
        return f"书名: {self.name}, 定价: {self.price}, 市场价: {self.market_price}, 出版社(外链): {self.publisher}"

    class Meta:
        """操作数据库中的表"""
        db_table = 'mybook'  # 重命名表名
        # managed = True
        verbose_name = '书籍表(Book)'  # 单数名, 用于显示在admin后台管理界面中, 影响详细列表的名字
        verbose_name_plural = '书籍表(Book)'  # 复数名, 用于显示在admin后台管理界面中, 影响导航模块中的名字


# class HostRelation(models.Model):
#     """
#     : 关联外链,多对多, 多个作者修改同一本书
#     : authors = models.ManyToManyField(Book, verbose_name='多,作者(外链)')
#     : 上述功能报错无法实现,所以手动创建
#     : 手动创建多对多关系表
#     """
#     book_d = models.ForeignKey(Book, on_delete=models.PROTECT, verbose_name='书籍(外链)')
#     author_d = models.ForeignKey(Author, on_delete=models.PROTECT, verbose_name='作者(外链)')
#     dates = models.DateTimeField(auto_now=True, verbose_name='添加时间')

#     def __str__(self) -> str:
#         return f"作者: {self.author_d}, 书籍: {self.book_d}, 添加时间: {self.dates}"

#     class Meta:
#         """操作数据库中的表"""
#         db_table = 'myhostrelation' # 重命名表名
#         # managed = True
#         verbose_name = '多对多表(myhostrelation)' # 单数名, 用于显示在admin后台管理界面中, 影响详细列表的名字
#         verbose_name_plural = '多对多表(myhostrelation)' # 复数名, 用于显示在admin后台管理界面中, 影响导航模块中的名字

class Wife(models.Model):
    """妻子表"""
    name = models.CharField(max_length=10, verbose_name='名字', null=False)
    age = models.IntegerField(null=False, default=1, verbose_name="年龄")
    phone = models.CharField(max_length=11, verbose_name='手机')
    dates = models.DateTimeField(auto_now=True, verbose_name='添加时间')

    # 关联外键, 一对一,  on_delete ->  为删除方式, models.CASCADE -> 是该条数据删除影响关联的数据条
    # models.PROTECT -> 是保护删除, 删除关联的数据库中的数据时会报异常, 以阻止被引用对象删除
    # SET_NULL -> 设置ForeignKey null; 只有null是true才有可能删除
    # SET_DEFAULT 将ForeignKey设置为其默认值, 必须设置ForeignKey的默认值,相当于关联另外一个表的字段,如果删除了关联第一个字段,则会自动选中第二个关联的数据或者字段
    author = models.OneToOneField(Author, models.PROTECT, verbose_name='外键')

    def __str__(self):
        return f"姓名: {self.name}, 年龄: {self.age}, 手机: {self.phone}, 添加时间: {self.dates}, 外键: {self.author}"

    class Meta:
        """操作数据库中的表"""
        db_table = 'mywife'  # 重命名表名
        verbose_name = '妻子表(wife)'
        verbose_name_plural = '妻子表(wife)'
